package edu.lingnan.rili.common;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.baomidou.mybatisplus.extension.service.IService;
import lombok.EqualsAndHashCode;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * @author xBaozi
 * @version 1.0
 * @classname DataListener
 * @description 自定义读Excel监听器
 * @date 2022/5/3 17:04
 */
@Slf4j
@Setter
@EqualsAndHashCode(callSuper = true)
public class DataListener<T> extends AnalysisEventListener<T> {
    /** 每隔100条存储数据库，然后清理list ，方便内存回收*/
    private static final int BATCH_COUNT = 100;

    private IService<T> service;

    public DataListener(IService<T> service){
        this.service = service;
    }

    /** 缓存的数据 */
    List<T> list = new ArrayList<T>();

    /**
     * @description 读取数据所执行的逻辑
     * @author xBaozi
     * @date 17:14 2022/5/3
     **/
    @Override
    public void invoke(T instance, AnalysisContext analysisContext) {
        log.info("读取到了数据{}", instance);
        list.add(instance);
        // 达到BATCH_COUNT存储一次数据库，防止数据几万条数据在内存，容易OOM
        if (list.size() >= BATCH_COUNT){
            this.saveData();
            list.clear();
        }
    }

    /**
     * @description 所有数据读取完毕之后将数据存放到数据库中
     * @author xBaozi
     * @date 17:15 2022/5/3
     **/
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        // 确保最后遗留的数据也存储到数据库
        this.saveData();
        log.info("所有数据导入成功");
    }

    /**
     * @description 将数据存放到数据库中
     * @author xBaozi
     * @date 17:09 2022/5/3
     **/
    private void saveData() {
        for (T data : list) {
            log.info("{}开始存放数据库……", data);
            try {
                this.service.save(data);
            } catch (Exception e) {
                log.info(e.getMessage());
            }
        }
    }
}
